package com.android.clinic.app.picture;

import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.annotation.Nullable;
import android.support.v4.content.FileProvider;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.SimpleItemAnimator;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;

import com.android.clinic.app.R;
import com.android.clinic.app.http.HttpClient;
import com.android.clinic.app.http.base.BaseObserver;
import com.android.clinic.app.http.utils.RxObservableUtils;
import com.android.clinic.app.picture.bean.FunctionConfig;
import com.android.clinic.app.picture.bean.LocalMedia;
import com.android.clinic.app.picture.bean.LocalMediaFolder;
import com.android.clinic.app.picture.bean.LocalMediaLoader;
import com.android.clinic.app.picture.bean.PictureConfig;
import com.android.clinic.app.utils.DisplayUtil;
import com.android.clinic.app.utils.FileUtils;
import com.android.clinic.app.utils.Utils;
import com.nanchen.compresshelper.CompressHelper;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;

/**
 * Created by cheng on 2018/2/6.
 */
public class PictureImageGridActivity extends PictureBaseActivity implements PictureImageGridAdapter.OnPhotoSelectChangedListener {

    private List<LocalMedia> images = new ArrayList<>();

    private PictureImageGridAdapter adapter;
    private String cameraPath;
    private List<LocalMediaFolder> folders = new ArrayList<>();
    private String imgUrl = "";

    @Override
    protected int getLayoutResId() {
        return R.layout.activity_grid_image;
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString(FunctionConfig.BUNDLE_CAMERA_PATH, cameraPath);
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        registerReceiver(receiver, "app.activity.finish", "app.action.refresh.data", "app.action.crop_data");
        boolean is_top_activity = getIntent().getBooleanExtra(FunctionConfig.EXTRA_IS_TOP_ACTIVITY, false);
        if (!is_top_activity) {
            // 第一次启动ImageActivity，没有获取过相册列表
            // 先判断手机是否有读取权限，主要是针对6.0已上系统
            if (hasPermission(Manifest.permission.READ_EXTERNAL_STORAGE)) {
                readLocalMedia();
            } else {
                requestPermission(FunctionConfig.READ_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE);
            }
        } else {
            selectMedias = (List<LocalMedia>) getIntent().getSerializableExtra(FunctionConfig.EXTRA_PREVIEW_SELECT_LIST);
        }
        folders = ImagesObservable.getInstance().readLocalFolders();
        if (folders == null) {
            folders = new ArrayList<>();
        }

        if (savedInstanceState != null) {
            cameraPath = savedInstanceState.getString(FunctionConfig.BUNDLE_CAMERA_PATH);
        }

        images = ImagesObservable.getInstance().readLocalMedias();

        if (images == null) {
            images = new ArrayList<>();
        }

        if (selectMedias == null) {
            selectMedias = new ArrayList<>();
        }

        Log.e("type:  ---", "" + type);


    }

    @Override
    protected void initView(@Nullable Bundle savedInstanceState) {
        super.initView(savedInstanceState);
        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        String folderName = getIntent().getStringExtra(FunctionConfig.FOLDER_NAME);
        if (folderName != null && !folderName.equals("")) {
            setTitleBarTitle(folderName);
        } else {
            setTitleBarTitle("最近照片");
        }
        setTitleBarLeftText("取消");
        setTitleBarRightText("完成");

        recyclerView.setHasFixedSize(true);
        recyclerView.addItemDecoration(new GridSpacingItemDecoration(spanCount, DisplayUtil.dip2px(this, 2), false));
        recyclerView.setLayoutManager(new GridLayoutManager(this, spanCount));
        // 解决调用 notifyItemChanged 闪烁问题,取消默认动画
        ((SimpleItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);

        String titleText = tvTitle.getText().toString().trim();
        if (showCamera) {
            if (!Utils.isEmpty(titleText) && titleText.startsWith("最近") || titleText.startsWith("Recent")) {
                // 只有最近相册 才显示拍摄按钮，不然相片混乱
                showCamera = true;
            } else {
                showCamera = false;
            }
        }
        adapter = new PictureImageGridAdapter(this, enablePreview, is_checked_num);
        recyclerView.setAdapter(adapter);
        if (selectMedias.size() > 0) {
            ChangeImageNumber(selectMedias);
            adapter.bindSelectImages(selectMedias);
        }
        adapter.bindImagesData(images);
        adapter.setOnPhotoSelectChangedListener(PictureImageGridActivity.this);
    }

    /**
     * 查询本地图片或视频
     */
    @Override
    protected void readLocalMedia() {
        new LocalMediaLoader(this, type).loadAllImage(folders1 -> {
            if (folders1.size() > 0) {
                // 取最近相册或视频数据
                LocalMediaFolder folder = folders1.get(0);
                images = folder.getImages();
                adapter.bindImagesData(images);
                PictureImageGridActivity.this.folders = folders1;
                ImagesObservable.getInstance().saveLocalFolders(folders1);
                ImagesObservable.getInstance().notifyFolderObserver(folders1);
            }
        });

    }

    @Override
    public void onTakePhoto() {
        // 启动相机拍照,先判断手机是否有拍照权限
        if (hasPermission(Manifest.permission.CAMERA)) {
            // 拍照
            startOpenCamera();
        } else {
            requestPermission(FunctionConfig.CAMERA, Manifest.permission.CAMERA);
        }
    }

    @Override
    public void onChange(List<LocalMedia> selectImages) {
        ChangeImageNumber(selectImages);
    }

    /**
     * start to camera、preview、crop
     */
    public void startOpenCamera() {
        Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (cameraIntent.resolveActivity(getPackageManager()) != null) {
            File cameraFile = FileUtils.createCameraFile(this, type);
            cameraPath = cameraFile.getAbsolutePath();
            Uri imageUri;
            String authority = getPackageName() + ".provider";
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                imageUri = FileProvider.getUriForFile(mContext, authority, cameraFile);//通过FileProvider创建一个content类型的Uri
            } else {
                imageUri = Uri.fromFile(cameraFile);
            }
            cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
            startActivityForResult(cameraIntent, FunctionConfig.REQUEST_CAMERA);
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_OK) {
            // on take photo success
            if (requestCode == FunctionConfig.REQUEST_CAMERA) {
                // 拍照返回
                File file = new File(cameraPath);
                sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file)));

                // 多选 返回列表并选中当前拍照的
                int duration = 0;
                if (type == LocalMediaLoader.TYPE_VIDEO) {
                    MediaMetadataRetriever mmr = new MediaMetadataRetriever();
                    mmr.setDataSource(file.getPath());
                    duration = Integer.parseInt(mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION));
                } else {
                    duration = Integer.parseInt(String.valueOf(System.currentTimeMillis()).substring(0, 10));
                }
                createNewFolder(folders);
                // 生成拍照图片对象
                LocalMedia media = new LocalMedia(file.getPath(), duration, duration, type);
                // 根据新拍照生成的图片，插入到对应的相册当中，避免重新查询一遍数据库
                LocalMediaFolder folder = getImageFolder(media.getPath(), folders);
                // 更新当前图片所属文件夹
                folder.getImages().add(0, media);// 插入到第一个位置
                folder.setImageNum(folder.getImageNum() + 1);
                folder.setFirstImagePath(media.getPath());
                folder.setType(type);

                // 取出最近文件夹 插入刚拍的照片或视频，并且如果大于30张，先移除最后一条在保存，因为最近文件夹中只显示30条数据
                LocalMediaFolder mediaFolder = folders.get(0);
                mediaFolder.setFirstImagePath(media.getPath());
                mediaFolder.setType(type);
                List<LocalMedia> localMedias = mediaFolder.getImages();
                if (localMedias.size() >= 100) {
                    localMedias.remove(localMedias.size() - 1);
                }
                List<LocalMedia> images = adapter.getImages();
                images.add(0, media);
                mediaFolder.setImages(images);
                mediaFolder.setImageNum(mediaFolder.getImages().size());
                // 没有到最大选择量 才做默认选中刚拍好的
                if (adapter.getSelectedImages().size() < maxSelectNum) {
                    List<LocalMedia> selectedImages = adapter.getSelectedImages();
                    selectedImages.add(media);
                    adapter.bindSelectImages(selectedImages);
                    ChangeImageNumber(adapter.getSelectedImages());
                }
                adapter.bindImagesData(images);
            }
        }
    }

    /**
     * 如果没有任何相册，先创建一个最近相册出来
     *
     * @param folders
     */
    private void createNewFolder(List<LocalMediaFolder> folders) {
        if (folders.size() == 0) {
            // 没有相册 先创建一个最近相册出来
            LocalMediaFolder newFolder = new LocalMediaFolder();
            String folderName = getString(R.string.lately_image);
            newFolder.setName(folderName);
            newFolder.setPath("");
            newFolder.setFirstImagePath("");
            newFolder.setType(type);
            folders.add(newFolder);
        }
    }

    private BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals("app.activity.finish")) {
                finish();
                overridePendingTransition(0, R.anim.slide_bottom_out);
            } else if (action.equals("app.action.refresh.data")) {
                List<LocalMedia> selectImages = (List<LocalMedia>) intent.getSerializableExtra(FunctionConfig.EXTRA_PREVIEW_SELECT_LIST);
                if (selectImages != null)
                    adapter.bindSelectImages(selectImages);
            } else if (action.equals("app.action.crop_data")) {
                // 裁剪返回的数据
                List<LocalMedia> result = (List<LocalMedia>) intent.getSerializableExtra(FunctionConfig.EXTRA_RESULT);
                if (result == null)
                    result = new ArrayList<>();
                handleCropResult(result);
            }
        }
    };

    private void handleCropResult(List<LocalMedia> result) {
        if (result != null) {
            onResult(result);
        }
    }

    /**
     * 对选择的图片进行压缩并上传
     * @param result
     */
    private void compressUploadFile(final List<LocalMedia> result) {
        List<File> oldListFile = new ArrayList<>();
        List<LocalMedia> compressList = new ArrayList<>();
        for (LocalMedia media : result) {
            File oldFile = new File(media.getPath());
            oldListFile.add(oldFile);
        }
        for (File file : oldListFile) {
            File newFile = CompressHelper.getDefault(getApplicationContext()).compressToFile(file);
            LocalMedia localMedia = new LocalMedia();
            localMedia.setPath(newFile.getAbsolutePath());
            compressList.add(localMedia);
        }
        MultipartBody.Builder builder = new MultipartBody.Builder()
                .setType(MultipartBody.FORM); //表单类型
        int imgSize = compressList.size();
        for (int i = 0; i < imgSize ; i++) {
            File file = new File(compressList.get(i).getPath());
            RequestBody imageBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
            builder.addFormDataPart("files" + i, file.getName(), imageBody);
        }
        List<MultipartBody.Part> parts = builder.build().parts();
        HttpClient.getHttpService().uploadMultipleTypeFile(parts)
                .compose(this.bindToLifecycle())
                .compose(RxObservableUtils.applySchedulers(loading, "上传中..."))
                .subscribe(new BaseObserver<String>() {
                    @Override
                    public void onSuccess(String s) {
                        imgUrl = s;
                        resultBack(result);
                    }

                    @Override
                    public void onFailure(String message) {
                        showToast(message);
                    }

                });
    }

    @Override
    protected void onBackClickListener(View v) {
        activityFinish(2);
    }

    @Override
    protected void onRightClickListener(View v) {
        List<LocalMedia> images = adapter.getSelectedImages();
        compressUploadFile(images);
    }

    /**
     * 图片选中数量
     *
     * @param selectImages
     */
    public void ChangeImageNumber(List<LocalMedia> selectImages) {
        boolean enable = selectImages.size() != 0;
        if (enable) {
            tvRight.setEnabled(true);
            tvRight.setAlpha(1.0f);
            setTitleBarRightText("完成(" + selectImages.size() + ")");
        } else {
            tvRight.setEnabled(false);
            tvRight.setAlpha(0.5f);
            setTitleBarRightText("完成");

        }
    }

    private void activityFinish(int type) {
        switch (type) {
            case 1:
                // 返回
                List<LocalMedia> selectedImages = adapter.getSelectedImages();
                ImagesObservable.getInstance().notifySelectLocalMediaObserver(selectedImages);
                finish();
                break;
            case 2:
                // 取消
                sendBroadcast("app.activity.finish");
                finish();
                overridePendingTransition(0, R.anim.slide_bottom_out);
                break;
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        switch (keyCode) {
            case KeyEvent.KEYCODE_BACK:
                activityFinish(1);
                return false;
        }
        return super.onKeyDown(keyCode, event);
    }

    private void resultBack(List<LocalMedia> images) {
        onResult(images);
    }

    public void onResult(List<LocalMedia> images) {
        // 因为这里是单一实例的结果集，重新用变量接收一下在返回，不然会产生结果集被单一实例清空的问题
        List<LocalMedia> result = new ArrayList<>();
        result.addAll(images);
        Log.e("grid_result.size()", result.size() + "");
        PictureConfig.OnSelectResultCallback resultCallback = PictureConfig.getPictureConfig().getResultCallback();
        if (resultCallback != null) {
            resultCallback.onSelectSuccess(result, imgUrl);
        }
        finish();
        sendBroadcast("app.activity.finish");
    }

    private LocalMediaFolder getImageFolder(String path, List<LocalMediaFolder> imageFolders) {
        File imageFile = new File(path);
        File folderFile = imageFile.getParentFile();

        for (LocalMediaFolder folder : imageFolders) {
            if (folder.getName().equals(folderFile.getName())) {
                return folder;
            }
        }
        LocalMediaFolder newFolder = new LocalMediaFolder();
        newFolder.setName(folderFile.getName());
        newFolder.setPath(folderFile.getAbsolutePath());
        newFolder.setFirstImagePath(path);
        imageFolders.add(newFolder);
        return newFolder;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (receiver != null) {
            unregisterReceiver(receiver);
        }
    }

}
